//
//  CharacterParser.m
//  iEVETracker
//
//  Created by Scott Guyer on 7/13/08.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import "CharacterParser.h"
#import "Character.h"
#import "Skill.h"
#import "DateUtility.h"
#import "InventoryItem.h"
#import "EVEdb.h"
#import "defs.h"



//<eveapi version="1">
//  <currentTime>2007-06-18 22:49:01</currentTime>
//  <result>
//    <characterID>150337897</characterID>
//    <name>corpslave</name>
//    <race>Minmatar</race>
//    <bloodLine>Brutor</bloodLine>
//    <gender>Female</gender>
//    <corporationName>corpexport Corp</corporationName>
//    <corporationID>150337746</corporationID>
//    <balance>190210393.87</balance>
//    <attributeEnhancers>
//      <intelligenceBonus>
//        <augmentatorName>Snake Delta</augmentatorName>
//        <augmentatorValue>3</augmentatorValue>
//      </intelligenceBonus>
//      <memoryBonus>
//        <augmentatorName>Halo Beta</augmentatorName>
//        <augmentatorValue>3</augmentatorValue>
//      </memoryBonus>
//    </attributeEnhancers>
//    <attributes>
//      <intelligence>6</intelligence>
//      <memory>4</memory>
//      <charisma>7</charisma>
//      <perception>12</perception>
//      <willpower>10</willpower>
//    </attributes>
//    <rowset name="skills" key="typeID">
//      <row typeID="3431" level="3" skillpoints="8000"/>
//      <row typeID="3413" level="3" skillpoints="8000"/>
//      <row typeID="21059" level="1" skillpoints="500"/>
//      <row typeID="3416" level="3" skillpoints="8000"/>
//    </rowset>
//  </result>
//  <cachedUntil>2007-06-18 23:49:01</cachedUntil>
//</eveapi>


@implementation CharacterParser

- (id) init
{
	[super init];
	
	return self;
}

- (void) handle_cachedUntil
{
	NSDateFormatter* df = [[NSDateFormatter alloc] init];
	[df setFormatterBehavior:NSDateFormatterBehavior10_4];
	//[df setDateFormat:@"%Y-%m-%d %H:%M:%S"];
	[df setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
	NSDate* cachedUntil = [df dateFromString:_currentString];
	NSDate* local = [DateUtility convertUTCToLocal:cachedUntil];
	_mychar.characterDataCachedUntil = local;
	[df release];
}

- (void) handle_name
{
	_mychar.name = [NSString stringWithString:_currentString];
}

- (void) handle_corporationName
{
	_mychar.corporationName = [NSString stringWithString:_currentString];
}

- (void) handle_race
{
	_mychar.race = [NSString stringWithString:_currentString];
}

- (void) handle_bloodLine
{
	_mychar.bloodline = [NSString stringWithString:_currentString];
}

- (void) handle_gender
{
	_mychar.gender = [NSString stringWithString:_currentString];
}

- (void) handle_balance
{
	_mychar.iskies = [NSString stringWithString:_currentString];
}


- (void) handle_intelligence
{
	[_mychar setAttribute:kPilotAttrTypeIntel withValue:[_currentString integerValue]];
}

- (void) handle_memory
{
	[_mychar setAttribute:kPilotAttrTypeMemory withValue:[_currentString integerValue]];
}

- (void) handle_charisma
{
	[_mychar setAttribute:kPilotAttrTypeCharisma withValue:[_currentString integerValue]];
}

- (void) handle_perception
{
	[_mychar setAttribute:kPilotAttrTypePerception withValue:[_currentString integerValue]];
}

- (void) handle_willpower
{
	[_mychar setAttribute:kPilotAttrTypeWillpower withValue:[_currentString integerValue]];
}

- (void) handle_intelligenceBonus
{
	_currentImplantType = kPilotAttrTypeIntel;
}

- (void) handle_memoryBonus
{
	_currentImplantType = kPilotAttrTypeMemory;
}

- (void) handle_charismaBonus
{
	_currentImplantType = kPilotAttrTypeCharisma;
}

- (void) handle_perceptionBonus
{
	_currentImplantType = kPilotAttrTypePerception;
}

- (void) handle_willpowerBonus
{
	_currentImplantType = kPilotAttrTypeWillpower;
}

- (void) handle_augmentatorValue
{
	[_mychar setImplantBonus:_currentImplantType withValue:[_currentString integerValue]];
}

- (Character*) parseXml:(NSData*)xmlData 
{
	if ( _parser == nil )
	{
		_parser = [NSXMLParser alloc];
	}
	[_parser initWithData:xmlData];
	[_parser setDelegate:self];
	
	_mychar = [[Character alloc] init];
	
	_accumSkillPoints = NO;
	if ( [_parser parse] )
	{
		_mychar.characterDataLastLoad = [NSDate date];
		return _mychar;
	}
	else
	{
		NSLog(@"error parsing character xml: %@", 
			  [_parser parserError]);
		return nil;
	}
}


- (void) parser:(NSXMLParser *)parser 
	didStartElement:(NSString *)elementName 
	namespaceURI:(NSString *)namespaceURI 
	qualifiedName:(NSString *)qualifiedName 
	attributes:(NSDictionary *)attributeDict
{
	if ( [elementName isEqualToString:@"rowset"] )
	{
		NSString* type = (NSString*) [attributeDict objectForKey:@"name"];
		if ( (type != nil) && [type isEqualToString:@"skills"] )
		{
			_accumSkillPoints = YES;
			_totalSP = 0;
		}
	}
	
	// Handle the case for implants
	// Here we just call the implant handler to set the current implant mode.
	// The augmentatorValue handler actually stores the value.
	NSRange r = [elementName rangeOfString:@"Bonus" options:(NSBackwardsSearch | NSAnchoredSearch)];
	if ( r.location != NSNotFound )
	{
		
		NSString* handlerName = [NSString stringWithFormat:@"handle_%@", elementName];
		SEL handler = NSSelectorFromString( handlerName);
		
		if ( [self respondsToSelector:handler] )
		{
			[self performSelector:handler];
		}
		
		return;
	}
	
	
	
	if ( _accumSkillPoints && [elementName isEqualToString:@"row"] )
	{
		NSString* spStr = (NSString*)[attributeDict objectForKey:@"skillpoints"];
		NSInteger sp = (spStr != nil) ? [spStr integerValue] : 0;
		if ( (sp == INT_MAX) || (sp == INT_MIN) )
		{
			NSLog(@"(und|ov)erflow: skillpoints = %@", spStr);
			sp = 0;
		}
		
		_totalSP += sp;
		
		NSString* typeID = [attributeDict objectForKey:@"typeID"];

		Skill* skillItem = [EVEdb getSkillWithId:[typeID integerValue]];
		if ( skillItem == nil )
		{
			NSLog(@"%s could not find matching item for item type ID %@", __FUNCTION__, typeID);
		}
		else
		{
			skillItem.points = sp;
			skillItem.level = [(NSString*)[attributeDict objectForKey:@"level"] integerValue];
//			[_mychar.skills setObject:skillItem forKey:typeID]; 
			[_mychar.skills setObject:skillItem forKey:skillItem.name]; 
			[skillItem release];
		}
						
		return;
	}
	
	
	r.location = 0;
	r.length = [_currentString length];
	[_currentString deleteCharactersInRange:r];
}


- (void) parser:(NSXMLParser *)parser 
	didEndElement:(NSString *)elementName 
	namespaceURI:(NSString *)namespaceURI 
	qualifiedName:(NSString *)qName
{
	
	if ( _accumSkillPoints && [elementName isEqualToString:@"rowset"] )
	{
		_accumSkillPoints = NO;		
		_mychar.skillPoints = _totalSP;
	}
	
	NSString* handlerName = [NSString stringWithFormat:@"handle_%@", elementName];
	SEL handler = NSSelectorFromString( handlerName);
	
	if ( [self respondsToSelector:handler] )
	{
		[self performSelector:handler];
	}
}


- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
	if ( _currentString == nil )
	{
		_currentString = [[NSMutableString alloc] initWithCapacity:255];
	}
	
	[_currentString appendString:string];
}



- (void) dealloc
{
	NSLog(@"%s 0x%x", __FUNCTION__, self);
	
	WIPE( _mychar)
	WIPE( _parser)
	WIPE( _currentString)
	
	[super dealloc];
}

@end
